package VWorldGameStudio;

import FCRendering.FCRBattleOrderConstant;
import FCRendering.FCRConstants;
import FCRendering.FCRMaster;
import FCRendering.ImageUtil;
import lombok.Getter;
import lombok.Setter;
import socket.FCRSocketClient;
import socket.FCRSocketServer;
import utils.FCMixUtil;
import Function.FCMutilPlayCache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import static FCRendering.FCRMaster.*;

/**
 * 用来存放战斗信息，战斗坐标等的,仅限是战斗中才有用
 * 存放的坐标要考虑，别的玩家是不是用你这个分辨率玩的
 */
public class FCPlayerBattleWrap extends Sprite {

    //用于携带目标hostId信息的，给服务端处理用，其它客机根本用不到
    public ArrayList<String> targetHostId;

    public FCPlayerBattleWrap(String uid, String name, double prop, int cx, int cy, int w, int h) {
        this.hostUid = uid;
        this.name = name;
        this.proportion = prop;
        this.coorX = cx;
        this.coorY = cy;
        this.w = w;
        this.h = h;
    }

    @Setter
    @Getter
    private boolean isBattleDriverTank = false;// 战斗时是否驾驶坦克
    @Setter
    @Getter
    private String hostUid;
    @Setter
    @Getter
    private String name;

    @Setter
    @Getter
    private double proportion;//原始屏幕比例

    @Setter
    @Getter
    private int coorX;//

    @Setter
    @Getter
    private int coorY;//

    @Setter
    @Getter
    private int w;//

    @Setter
    @Getter
    private int h;//


    //参考看FCRBattleOrder.java
    @Setter
    @Getter
    private int battleAttackOrder = 0;

    @Setter
    @Getter
    private int BattlePlayerSelectMonster = -1;// 玩家选中的要攻击的对象


    /**
     * //参考看FCRBattleOrder.java
     */
    @Setter
    @Getter
    /**
     *  玩家选择的菜单选项,比如攻击是徒手呢还是拿武器呢
     *  1 是人类徒手， 2是人类手中武器
     *  3 是坦克主炮 4 是坦克主炮+特俗炮弹
     *  5 是坦克副炮  6 是SE
     */
    private int BattlePlayerSelectMenu = -1;

    @Getter
    private boolean battleReady = false;//回合准备ok

    public void setBattleReady(boolean flag){
        battleReady = flag;
        if(gameSave.HOST_UID.equals(getHostUid()) && flag){
            checkAndSyncBattleWrap();
        }
    }

    @Setter
    @Getter
    private int BattlePlayerSelectPaoDanIndex = -1;//当使用炮弹时的坦克对应index

    @Setter
    @Getter
    private int BattlePlayerSelectItem = -1;//使用道具,是坦克道具和人类道具喔

    @Setter
    @Getter
    private int BattlePlayerSelectItemMode = -1;//2 是坦克背包道具 1是人类背包道具

    @Setter
    @Getter
    private int BattleUseItemType = -1;//1是对敌人使用{BattlePlayerSelectMonster}，2是对自己人使用{BattlePlayerSelectPlayer}

    @Setter
    @Getter
    private String BattlePlayerSelectPlayer = "";// 玩家选中的玩家,uid+","+name,对自己人使用的

    /**
     * 用于记录所有持续性状态属性的map,不用同步给对方
     */
    private HashMap<String, FCLongTermState> longTermMap = new HashMap<>();

    public static FCPlayerBattleWrap findBattleWrapByName(String uid, String name) {
        for (FCPlayerBattleWrap fcPlayerBattleWrap : FCRMaster.fcv.getBattleWraps()) {
            if (fcPlayerBattleWrap.getHostUid().equals(uid) && fcPlayerBattleWrap.getName().equals(name)) {
                return fcPlayerBattleWrap;
            }
        }
        return null;
    }

    public static ArrayList<FCPlayerBattleWrap> findAllWrapByHostId(String hostUid) {
        ArrayList<FCPlayerBattleWrap> ret = new ArrayList<>(0);
        for (FCPlayerBattleWrap fcPlayerBattleWrap : FCRMaster.fcv.getBattleWraps()) {
            if (fcPlayerBattleWrap.getHostUid().equals(hostUid)) {
                ret.add(fcPlayerBattleWrap);
            }
        }
        return ret;
    }

    //TODO 和canThisBattle的区别是，睡眠只是睡几回合，但麻痹是全麻，只能团灭
    public static boolean canThisEndBattle(FCPlayerBattleWrap wrap){
        if(wrap.getLongTermVal(FCRBattleOrderConstant.S_Paralysis) != -1) {
            return false;
        }
        return true;
    }

    public static boolean canThisBattle(FCPlayerBattleWrap wrap){
        if(wrap.getLongTermVal(FCRBattleOrderConstant.S_Sleep) != -1){
           return false;
        }
        if(wrap.getLongTermVal(FCRBattleOrderConstant.S_Paralysis) != -1) {
            return false;
        }
        if(wrap.getLongTermVal(FCRBattleOrderConstant.S_Confusion) != -1) {
            return false;
        }
        return true;
    }

    //判断是否在混乱中
    public boolean isInConfusion(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Confusion);
        return val != -1;
    }

    public boolean isInSleep(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Sleep);
        return val != -1;
    }

    public boolean isInParalysis(){
        int val = getLongTermVal(FCRBattleOrderConstant.S_Paralysis);
        return val != -1;
    }
    /**
     * 回合结束必须调用这里，恢复所有持续性buff的东西
     */
    public void endOfRound() {
        ArrayList<FCLongTermState> tmp = new ArrayList<>();
        Iterator<Map.Entry<String, FCLongTermState>> iterator = longTermMap.entrySet().iterator();
        FCPlayerInfo tmpP = FCMutilPlayCache.findPlayerByName(getHostUid(), getName());
        if(tmpP == null){
            return;
        }
        FCTank drivinTank = null;
        //检查一下坐的坦克
        if (isBattleDriverTank()) {
            drivinTank = tankLib.getTankOfID(tmpP.getPlayertank1(), tmpP.getPlayertankHostId());
            if(drivinTank != null && drivinTank.isAcidState()){
                FCMixUtil.stepCheckAcidAndSubDefense(drivinTank);
            }
        }
        while (iterator.hasNext()) {
            FCLongTermState e = iterator.next().getValue();
            int hurt = 0;
            int val = e.value;
            if (e.stateName.equals(FCRBattleOrderConstant.S_Acid)) {
                //TODO 酸
                hurt = Math.max(5, (int)(val*(1f-(float)tmpP.getPlayerAcidDefend()/100)));
                tmpP.subBlood(hurt);
                fcv.getMessage().add(tmpP.getChName()+" 受到酸伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Gas)){
                //TODO 毒气
                if(drivinTank != null && (drivinTank.isOpenKongTiao() || drivinTank.isOpenQiShan())){
                    val = (int)(val*0.6);
                }
                hurt = Math.max(5, (int)(val*(1f-(float)tmpP.getPlayerGasDefend()/100)));
                tmpP.subBlood(hurt);
                fcv.getMessage().add(tmpP.getChName()+" 受到毒伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Fire)){
                //TODO 火焰
                if(drivinTank != null && (drivinTank.isOpenKongTiao() || drivinTank.isOpenLengFengJi())){
                    val = (int)(val*0.6);
                }
                hurt = Math.max(5, (int)(val*(1f-(float)tmpP.getPlayerFireDefend()/100)));
                tmpP.subBlood(hurt);
                fcv.getMessage().add(tmpP.getChName()+" 受到火伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_Frozen)){
                //TODO 冰冻
                if(drivinTank != null && (drivinTank.isOpenKongTiao() || drivinTank.isOpenNuanFengJi())){
                    val = (int)(val*0.6);
                }
                hurt = Math.max(5, (int)(val*(1f-(float)tmpP.getPlayerFrozenDefend()/100)));
                tmpP.subBlood(hurt);
                fcv.getMessage().add(tmpP.getChName()+" 受到冰冻伤害"+hurt);
                fcv.showMessage();
            }else if(e.stateName.equals(FCRBattleOrderConstant.S_AddBlood)){
                //TODO 回血
                int bl = tmpP.getBlood() + e.value;
                bl = Math.min(bl, tmpP.getBloodMax());
                bl = Math.max(0, bl);
                tmpP.setBlood(bl);
                fcv.getMessage().add(tmpP.getChName()+" HP加"+bl);
                fcv.showMessage();
            }
            if (e.isRoundEnd()) {
                tmp.add(e);
            }else {
                if(e.stateName.equals(FCRBattleOrderConstant.S_Sleep)){
                    //TODO 睡眠
                    fcv.getMessage().add(tmpP.getChName()+" 睡眠中无法战斗");
                    fcv.showMessage();
                }else if(e.stateName.equals(FCRBattleOrderConstant.S_Paralysis)){
                    //TODO 麻痹
                    fcv.getMessage().add(tmpP.getChName()+" 麻痹了无法战斗");
                    fcv.showMessage();
                }else if(e.stateName.equals(FCRBattleOrderConstant.S_Confusion)){
                    //TODO 混乱
                    fcv.getMessage().add(tmpP.getChName()+" 混乱了");
                    fcv.showMessage();
                }
            }
        }
        for (FCLongTermState s : tmp) {
            longTermMap.remove(s.stateName);
        }
    }

    //战斗中复活的时候使用
    public void rebornRemoveAllState(){
        longTermMap.clear();
    }

    /**
     * @param state  什么状态
     * @param val    什么数值
     * @param rounds 持续多少回合
     */
    public void addlongTermState(String state, int val, int rounds) {
        FCLongTermState e = longTermMap.get(state);
        if (e != null) {
            longTermMap.remove(state);
        }
        //if (e == null) {
            //状态不叠加，直接覆盖
        longTermMap.put(state, new FCLongTermState(state, val, rounds));
        System.out.println("addlongTermState "+state+" "+val+" rounds:"+rounds);
      //  }
    }

    /**
     * 使用药物恢复了
     * @param state
     */
    public void removeLongTermState(String state){
        longTermMap.remove(state);
    }


    //没有这个状态就返回-1
    public int getLongTermVal(String state) {
        FCLongTermState e = longTermMap.get(state);
        if (e != null) {
            return e.value;
        }
        return -1;
    }

    //用于绘制图标的,判断是否有图标的
    public ArrayList<String> getAllLongTermState(){
        ArrayList<String> tmp = new ArrayList<>(0);
        Iterator<Map.Entry<String, FCLongTermState>> iterator = longTermMap.entrySet().iterator();
        while (iterator.hasNext()) {
            FCLongTermState e = iterator.next().getValue();
            if(ImageUtil.checkContainImage(e.stateName)) {
                tmp.add(e.stateName);
            }
        }
        return tmp;
    }

    /**
     * 仅战斗结束后使用的
     * @return
     */
    public ArrayList<FCLongTermState> getRemainLongTermState(){
        ArrayList<FCLongTermState> tmp = new ArrayList<>(0);
        Iterator<Map.Entry<String, FCLongTermState>> iterator = longTermMap.entrySet().iterator();
        while (iterator.hasNext()) {
            FCLongTermState e = iterator.next().getValue();
            if(e.rounds == -1){
                tmp.add(e);
            }
        }
        return tmp;
    }

    /***
     * 用来检查并发送战斗已经准备的
     */
    public void checkAndSyncBattleWrap() {
        if (fcv.isSever()) {
            FCRSocketServer.getIn().battelReady(this);
        } else if (fcv.isClient()) {
            FCRSocketClient.getIn().battelReady(this);
        }
    }
}
